package com.jsb.laundry.common.utils.sf;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @data 2023/4/13 13:59
 */
public class SFUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(SFUtil.class);

    /**
     * 调用顺丰服务接口
     *
     * @param serviceCode 服务代码，在 SFServiceCodeEnum 中获取
     * @param msgData     构建不同服务构建不同请求参数即可
     */
    public static String SFRequest(String serviceCode, String msgData) {
        // 请求号requestID
        String requestID = UUID.randomUUID().toString().replace("-", "");
        LOGGER.info("请求号requestID：" + requestID);
        //客户校验码    使用顺丰分配的客户校验码
        String checkWord = SFProperties.checkWord;
        //时间戳 取报文中的timestamp（调用接口时间戳）
        String timestamp = String.valueOf(System.currentTimeMillis());
        LOGGER.info("时间戳：" + timestamp);
        //业务报文  去报文中的msgData（业务数据报文）

        //将业务报文+时间戳+校验码组合成需加密的字符串(注意顺序)
        String toVerifyText = msgData + timestamp + checkWord;
        //因业务报文中可能包含加号、空格等特殊字符，需要urlEnCode处理
        try {
            toVerifyText = URLEncoder.encode(toVerifyText, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        //进行Md5加密
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            md5.update(toVerifyText.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        byte[] md = md5.digest();
        //通过BASE64生成数字签名
        String msgDigest = new String(new BASE64Encoder().encode(md));
        LOGGER.info("数字签名：" + msgDigest);

        Map<String, String> params = new HashMap<>();
        params.put("requestID", requestID);
        params.put("msgDigest", msgDigest);
        params.put("msgData", msgData);
        params.put("timestamp", timestamp);
        params.put("partnerID", SFProperties.partnerId);
        params.put("serviceCode", serviceCode);

        String result = null;
        try {
            result = SFHttpClientUtil.post(SFProperties.callUrlBox, params);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        LOGGER.info("调用顺丰服务接口,入参:[{},{}],出参:{}", serviceCode, msgData, result);
        return result;
    }

    /**
     * 解析顺丰下单后返回的数据-（顺丰单号）
     *
     * @param sfResponse 顺丰下单返回json
     * @return
     */
    public static String getSFWaybillNo(String sfResponse) {
        JSONObject jsonObject = JSONObject.parseObject(sfResponse);
        JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
        String waybillNo = "";
        String code = apiResultData.getString("errorCode");
        JSONObject msg = apiResultData.getJSONObject("errorMsg");
        if ("S0000".equals(code)) { //下单正常时
            JSONObject msgData = apiResultData.getJSONObject("msgData");
            JSONArray waybillNoInfoList = msgData.getJSONArray("waybillNoInfoList");
            for (Object o : waybillNoInfoList) {
                JSONObject obj = JSONObject.parseObject(o.toString());
                waybillNo = obj.getString("waybillNo");
                break;
            }
        }
        LOGGER.info("顺丰下单返回信息。code:{},msg:{}，data:{},顺丰单号:{}", code, msg, apiResultData, waybillNo);
        return waybillNo;
    }

    /**
     * 解析顺丰路由
     *
     * @param sfResponse
     * @return
     */
    public static String getSFLogisticsTrack(String sfResponse) {
        JSONObject jsonObject = JSONObject.parseObject(sfResponse);
        JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
        String opCode = "";
        String code = apiResultData.getString("errorCode");
        JSONObject msg = apiResultData.getJSONObject("errorMsg");
        if ("S0000".equals(code)) { //下单正常时
            JSONObject msgData = apiResultData.getJSONObject("msgData");
            JSONArray routeResps = msgData.getJSONArray("routeResps");
            String jsonString = JSONObject.toJSONString(routeResps.get(0));
            JSONObject jsonObject1 = JSONObject.parseObject(jsonString);
            JSONArray routes = jsonObject1.getJSONArray("routes");
            if (routes.size() > 0) {
                JSONObject jsonObject2 = routes.getJSONObject(routes.size() - 1);
                opCode = jsonObject2.getString("opCode");
            }
        }
        LOGGER.info("顺丰物流轨迹。code:{},msg:{}，data:{},最新一条物流轨迹状态码:{}", code, msg, apiResultData, opCode);
        return opCode;
    }


}
